#include <iostream>
#include <cstdlib>
#include <tr1/memory>

using namespace std;

void testPortee();
tr1::shared_ptr<string> testVariableRetour();
void testPassageReference(tr1::shared_ptr<string> ptr_str);

int main(int argc, char** argv)
{
    tr1::shared_ptr<string> ptr_str;

    cout << endl <<"Test de portee:" << endl;
    testPortee();
    cout << "##############" << endl;

    cout << endl <<"Test de Variable de retour:" << endl;
    ptr_str = testVariableRetour();
    cout << "ptr_str pointe-t'il vers quelquechose? "<< ((ptr_str.use_count() == 1) ? "OUI" : "NON") <<endl;
    cout << "si oui, le contenu de la variable pointé est: "<< ((ptr_str.use_count() == 1) ? *ptr_str : "ptr_str ne pointe vers rien") <<endl;
    cout << "##############" << endl;

    cout << endl <<"Test de passage par reference:" << endl;
    testPassageReference(ptr_str);
    cout << "Contenu de la variable pointé par \"ptr_str\": " <<*ptr_str <<" | adresse["<<ptr_str<<"] | nombre de shared_pointer pointant la variable: "<<ptr_str.use_count()<<endl;
    cout << "##############" << endl;

    return EXIT_SUCCESS;
}

void testPortee()
{
    tr1::shared_ptr<string> ptr_str;

    //Ces accolades servent à délimiter un bloc pour limiter la durée de vie de ptr_str2 et ptr_str3.
    {

        tr1::shared_ptr<string> ptr_str2(new string("Je suis la chaîne de caractère 1"));
        cout << "Contenu de la variable pointé par \"ptr_str2\": "<<*ptr_str2<<" | adresse["<<ptr_str2<<"] | nombre de shared_pointer pointant la variable: "<<ptr_str2.use_count()<<endl;

        tr1::shared_ptr<string> ptr_str3(ptr_str2);
        cout << "Contenu de la variable pointé par \"ptr_str3\": " <<*ptr_str3 <<" | adresse["<<ptr_str3<<"] | nombre de shared_pointer pointant à la variable: "<<ptr_str3.use_count()<<endl;

        ptr_str = ptr_str2;
        cout << "Contenu de la variable pointé par \"ptr_str\": " <<*ptr_str <<" | adresse["<<ptr_str<<"] | nombre de shared_pointer pointant la variable: "<<ptr_str.use_count()<<endl;
    }

    cout << "Contenu de la variable pointé par \"ptr_str\": " <<*ptr_str <<" | adresse["<<ptr_str<<"] | nombre de shared_pointer pointant la variable: "<<ptr_str.use_count()<<endl;
}

tr1::shared_ptr<string> testVariableRetour()
{
    tr1::shared_ptr<string> ptr_str(new string("Je suis la chaîne de caractère 1"));
    return  ptr_str;
}

void testPassageReference(tr1::shared_ptr<string> ptr_str)
{
    *ptr_str = "Avant j'étais \"Je suis la chaîne de caractère 1\"... Désormais je serais le plus grand lama du monde!!!!!";
}
